package com.manager
{
	import com.game.avatar.Animation;
	import com.game.avatar.Avatar;
	import com.game.avatar.Frame;
	import com.game.events.GameEventDispatcher;
	import com.resLoader.Resources;
	
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.filters.BitmapFilter;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;

	/**
	 * 动作，特效管理
	 * @author yangyang
	 *
	 */
	public class AnimationManager
	{
		private static var instance : AnimationManager;

		private var animtionsData : Dictionary = new Dictionary();

		private var effectAnimations : Dictionary = new Dictionary();

		/**
		 * 加载器
		 */
		private var resources : Resources;

		public function AnimationManager()
		{
			resources = Resources.getInstance();
		}


		/**
		 * 单列
		 * @return
		 *
		 */
		public static function getInstance() : AnimationManager
		{
			if (instance == null)
			{
				instance = new AnimationManager();
			}
			return instance;
		}

		public function createAvatar(id : String, weaponId : String, wingId : String) : Avatar
		{
			var avatar : Avatar = new Avatar(id);
			var actionDirAnimation : Dictionary = getAvatarAnimation(id, weaponId, wingId);
			var cloneAnimations : Dictionary = new Dictionary();

			for (var key : String in actionDirAnimation)
			{
				var animation : Animation = actionDirAnimation[key];
				cloneAnimations[key] = animation.clone();
			}
			avatar.actionsDirAnimation = cloneAnimations;
			return avatar;
		}

		/**
		 * 创建人物的动作动画
		 * @param id
		 * @param weaponId
		 * @return
		 *
		 */
		public function createAvatarAnimation(id : String, weaponId : String, wingId : String) : Dictionary
		{
			var avatar_index : Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 30];
			var actionClass : Class;
			var composedAnimation : Animation;
			var animation : Animation;
			var animationMovie : MovieClip;
			var actionDirAnimation : Dictionary = new Dictionary();
			var actionType : String;
			var animationId : String;
			var action_types : Array;
			var index : int;
			var len : int = avatar_index.length;

			for (var i : int = 0; i <= len; i++)
			{
				composedAnimation = new Animation();
				var animations : Array = [];
				index = avatar_index[i];

				action_types = ["body", "weapon1", "wing", "other"];

				for each (actionType in action_types)
				{
					if (actionType == "weapon1")
					{
						animationId = actionType + "." + weaponId + "." + index;
					}
					else if (actionType == "wing")
					{
						animationId = actionType + "." + wingId + "." + index;
					}
					else
					{
						animationId = actionType + "." + id + "." + index;
					}

					actionClass = resources.getClass(animationId);

					if (actionClass == null)
					{
						continue;
					}
					animationMovie = new actionClass() as MovieClip;
					animation = new Animation();
					animation.createAnimationFrames(animationMovie);
					animations.push(animation);
				}

				composedAnimation.frames = composeAnimations(animations, 1000 / 12);
				actionDirAnimation[index] = composedAnimation;
			}
			animtionsData[id + "," + weaponId + "," + wingId] = actionDirAnimation;
			return animtionsData;
		}

		/**
		 * 合成动作Frame
		 * @param index
		 * @return
		 *
		 */
		private function composeAnimations(animations : Array, duration : int) : Array
		{
			var centerX : int = 200;
			var centerY : int = 200;

			var bd : BitmapData = new BitmapData(400, 400, true, 0);
			var boundRect : Rectangle = new Rectangle();
			var point : Point = new Point();
			var frame : Frame;
			var frames : Array = [];

			if (animations.length == 0)
			{
				return null;
			}

			var len : int = animations[0].frameCount;

			for (var i : int = 0; i < len; i++)
			{
				boundRect.left = int.MAX_VALUE;
				boundRect.top = int.MAX_VALUE;
				boundRect.bottom = int.MIN_VALUE;
				boundRect.right = int.MIN_VALUE;

				bd.fillRect(bd.rect, 0);

				for each (var animation : Animation in animations)
				{
					if (animation == null)
						continue;
					frame = animation.getFrame(i);

					if (frame == null || frame.data == null)
					{
						//trace(id + "缺少Frame:" + i);
						continue;
					}
					point.x = centerX + frame.offsetX;
					point.y = centerY + frame.offsetY;
					//计算该合成帧的最小包围框
					bound(boundRect, point.x, point.y, frame.data.width, frame.data.height);
					bd.copyPixels(frame.data, frame.data.rect, point, null, null, true);
				}
				var bmd : BitmapData = new BitmapData(boundRect.width, boundRect.height, true, 0);
				point.x = 0;
				point.y = 0;
				bmd.copyPixels(bd, boundRect, point, null, null, true);

				var composdFrame : Frame = new Frame();
				composdFrame.data = bmd;
				composdFrame.offsetX = boundRect.x - centerX;
				composdFrame.offsetY = boundRect.y - centerY;
				composdFrame.duration = duration;
				frames.push(composdFrame);
			}
			bd.dispose();

			return frames;
		}

		private function bound(dest : Rectangle, left : int, top : int, width : int, height : int) : void
		{
			var right : int = left + width;
			var bottom : int = top + height;

			if (left < dest.left)
			{
				dest.left = left;
			}

			if (top < dest.top)
			{
				dest.top = top;
			}

			if (right > dest.right)
			{
				dest.right = right;
			}

			if (bottom > dest.bottom)
			{
				dest.bottom = bottom;
			}
		}

		private function createAnimationByClassName(className : String) : Animation
		{
			var actionClass : Class = resources.getClass(className);
			var animationMovie : MovieClip;

			if (actionClass == null)
			{
				return null;
			}

			animationMovie = new actionClass() as MovieClip;
			var animation : Animation = new Animation();
			animation.createAnimationFrames(animationMovie);
			return animation;
		}

		/**
		 * 创建特效动画
		 * @param id
		 * @return
		 *
		 */
		public function createEffectAnimation(id : String) : Animation
		{
			//Print.warning("生成特效:", id);
			var animation : Animation = new Animation();
			var actionClass : Class = resources.getClass(id);

			if (actionClass == null)
			{
				return null;
			}

			var playSpeed : int;



			if (playSpeed == 0)
			{
				playSpeed = 1000 / 12;
			}
			var effectMovie : MovieClip = new actionClass() as MovieClip;
			animation.createAnimationFrames(effectMovie, playSpeed);
			effectAnimations[id] = animation;
			return animation;
		}

		/**
		 * 获得人物动作动画
		 * @param id
		 * @return
		 *
		 */
		public function getAvatarAnimation(id : String, weaponId : String, wingId : String) : Dictionary
		{
			return animtionsData[id + "," + weaponId + "," + wingId];
		}

		/**
		 * 获得特效动画
		 * @param id
		 * @return
		 *
		 */
		public function getEffectiAnimation(id : String) : Animation
		{
			var animation : Animation = effectAnimations[id];

			if (animation == null)
			{
				animation = createEffectAnimation(id);

				if (animation == null)
				{
					GameEventDispatcher.sendError("生成特效错误ID：", id);
					return null;
				}
				return animation.clone();
			}
			return animation.clone();
		}

		/**
		 * 清理掉动作动画
		 *
		 */
		public function clearAnimation() : void
		{
			var animation : Animation;

			for (var key : String in animtionsData)
			{
				var data : Dictionary = animtionsData[key];

				for (var key1 : String in data)
				{
					animation = data[key1];
					animation.destroy(true);
					delete data[key1];
				}
				delete animtionsData[key];
			}
		}

		/**
		 * 清理掉特效动画。
		 *
		 */
		public function clearEffect() : void
		{
			for (var key : String in effectAnimations)
			{
				var effect : Animation = effectAnimations[key];
				effect.destroy(true);
				delete effectAnimations[key];
			}
		}
	}
}